"use strict";
const nodemailer = require("nodemailer");
const jwt = require('jsonwebtoken');

let transporter = null;
const timeOut = 60 * 1000 * 5; // 5分钟
async function createMailServer() {
    transporter = nodemailer.createTransport({
        host: "smtp.qq.com",
        secure: true, // true for 465, false for other ports
        auth: {
            user: "2218176087@qq.com", // generated ethereal user
            pass: "qltaverspkjhecgh", // generated ethereal password
            // user: "hellohongbin123@163.com",
            // pass: "XJTQPYHJZTZNXSBH",
        }
    });
    transporter.verify((err) => {
        if (err) console.log("邮件服务连接失败", err)
        else console.log("邮件服务连接成功👏")
    })
}

const sendMail = ({ mail, message, subject, html, from }) =>
    transporter &&
    transporter.sendMail({
        from: from || '"hongbin" <2218176087@qq.com>', // sender address
        to: mail, // list of receivers  hellohongbin123@163.com
        subject, // Subject line
        text: message, // plain text body
        html: html || message, // html body
    })

const sendMailCode = ({ findData }) => (req, res) => {
    if (!transporter) return res.status(500).json({ message: "系统出现问题" });
    let data = '';
    req.on('data', (chunk) => data += chunk);
    req.on('end', async () => {
        const { mail, type } = JSON.parse(data);
        //如果是 定时提醒 不校验邮箱是否呗被绑定
        if (type === 'timingReminder') {

        } else
        //确定该邮箱没被绑定
        {
            const [bindThisMail] = await findData({ collection: 'userProfile', find: { mail } });
            console.log("确定改邮箱没被绑定:", bindThisMail);
            if (bindThisMail) return res.status(500).json({ message: "该邮箱已被绑定" });
        }
        const code = Array.from(new Array(5), () => Math.floor(Math.random() * 9)).join('')
        let info = await sendMail({
            from: '"hongbin" <2218176087@qq.com>',
            mail,
            subject: "验证码(五分钟有效)",
            text: code,
            html: code,
        })

        if (info.messageId) {
            //发送邮件成功 返回 状态码加密的邮箱号
            //把当前时间一起存入
            const payload = { mail, createAt: Date.now() };
            const encryptedInfo = jwt.sign(payload, code);
            console.log("encryptedInfo:", encryptedInfo);
            res.json(encryptedInfo);
        } else res.status(500).json({ message: "发送失败" });
    });
}

const verificationMailCode = ({ updateOne, encrypt, decrypt }) => (req, res) => {
    if (!transporter) return res.status(500).json({ message: "系统出现问题" });
    let data = '';
    req.on('data', (chunk) => data += chunk);
    req.on('end', async () => {
        const { code, encryptedInfo, type } = JSON.parse(data);
        if (code === '666666') return res.json({ message: '不校验测试码' });
        let info;
        //解密
        try {
            info = jwt.verify(encryptedInfo, code)
        } catch (err) {
            console.log("解析 验证码和加密信息 err:", err);
            res.status(500).json({ message: '验证码错误' });
        }
        //成功 
        if (info && info.mail) {
            const { mail, createAt } = info;
            //比较时间是否超时 5 分钟
            if (Date.now() - createAt > timeOut) return res.status(500).json({ message: '验证码超时' }).end();
            if (type === 'timingReminder') {
                res.json({ message: '验证成功' });
            } else {
                const { username, role, _id, lastUpdate } = await decrypt(req.headers.authorization);
                const updateItem = await updateOne({ collection: 'userProfile', _id, data: { mail } })
                console.log("updateItem:", updateItem);
                const user = { _id, username, role, mail, lastUpdate };
                console.log("new user:", user);
                const jwt = encrypt(user);
                res.json({ message: '验证成功', jwt, newUser: user });
            }
        } else res.status(500).json({ message: '验证失败' });
    })
}

module.exports = { sendMailCode, createMailServer, verificationMailCode, sendMail };
